package com.zb.frame.modules.sys.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zb.frame.base.model.MPPage;
import com.zb.frame.base.model.R;
import com.zb.frame.modules.common.controller.AbstractController;
import com.zb.frame.modules.monitor.enums.LogModule;
import com.zb.frame.modules.monitor.enums.LogType;
import com.zb.frame.modules.monitor.service.LogService;
import com.zb.frame.modules.sys.entity.RelRoleMenu;
import com.zb.frame.modules.sys.entity.RelUserRole;
import com.zb.frame.modules.sys.entity.Role;
import com.zb.frame.modules.sys.entity.User;
import com.zb.frame.modules.sys.service.RelRoleMenuService;
import com.zb.frame.modules.sys.service.RelUserRoleService;
import com.zb.frame.modules.sys.service.RoleService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author bangZZ
 * @since 2020-06-04
 */
@RestController
@RequestMapping("/sys/role")
public class RoleController extends AbstractController{

    @Autowired
    RoleService roleService;

    @Autowired
    RelRoleMenuService roleMenuService;

    @Autowired
    RelUserRoleService userRoleService;

    @Autowired
    LogService logService;

    @ApiOperation(value = "getRoles", notes = "获取所有角色列表信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "当前页数", dataType = "String"),
        @ApiImplicitParam(name = "limit", value = "一页显示数量", dataType = "String"),
        @ApiImplicitParam(name = "name", value = "角色名称/角色别名", dataType = "String")
    })
    @GetMapping("/list")
    @RequiresPermissions("sys:role:view")
    public R getRoles(Integer page, Integer limit, String name) {
        Integer currPage = (page == null) ? 1 : page;
        Integer pageSize = (limit == null) ? 10 : limit;
        Page<Role> pageInfo = new Page<>(currPage, pageSize);
        Map<String, Object> query = new HashMap<>();
        query.put("name", name);
        MPPage retData = roleService.getRoleList(pageInfo, query);
        return R.ok(retData);
    }

    @ApiOperation(value = "getRole", notes = "根据角色Id获取所有角色信息")
    @ApiImplicitParam(name = "id", value = "角色Id", dataType = "String")
    @GetMapping("/info/{id}")
    @RequiresPermissions("sys:role:view")
    public R getRole(@PathVariable String id) {
        Role role = roleService.getById(id.toUpperCase());
        return (role != null) ? R.ok(role) : R.error(404, "","失败，角色不存在！");
    }


    @ApiOperation(value = "newRole", notes = "新增角色")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "roleId", value = "角色名称", dataType = "String"),
        @ApiImplicitParam(name = "roleName", value = "角色别名", dataType = "String"),
        @ApiImplicitParam(name = "roleDesc", value = "角色描述", dataType = "String")
    })
    @PostMapping("/info")
    @RequiresPermissions("sys:role:add")
    public R newRole(@RequestBody Role data) {
        String roleId = data.getRoleId().toUpperCase();
        if (roleId.equals("relUser".toUpperCase()))
            return R.error("失败，被禁用的角色名称!");
        boolean isExist = roleService.isExist(roleId);
        if (isExist)
            return R.error("失败，角色已存在!");
        Role role = roleService.addRole(data);
        if (role != null) {
            // 添加日志
            String newValue = JSON.toJSONString(role);
            logService.addLog(LogModule.SYSROLE, LogType.ADD,"", newValue, role.getRoleId(), this.getUserId(),"新增角色[" + role.getRoleName() + "]成功");
            return R.ok("成功！",role.getRoleId());
        } else {
            return R.error("失败!");
        }
    }

    @ApiOperation(value = "updateRole", notes = "修改角色")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "roleName", value = "角色别名", dataType = "String"),
        @ApiImplicitParam(name = "roleDesc", value = "角色描述", dataType = "String")
    })
    @PutMapping("/info/{id}")
    @RequiresPermissions("sys:role:edit")
    public R updateRole(@PathVariable String id, @RequestBody Role data) {
        data.setRoleId(id.toUpperCase());
        String oldValue = JSON.toJSONString(data);
        Role newRole = roleService.updateRole(data);
        if (newRole == null)
            return R.error("失败,角色不存在！");
        String newValue = JSON.toJSONString(newRole);
        // 添加日志
        logService.addLog(LogModule.SYSROLE, LogType.UPDATE, oldValue, newValue, newRole.getRoleId(), this.getUserId(), "修改角色[" + newRole.getRoleId()+ "]成功");
        return R.ok("成功！");
    }

    @ApiOperation(value = "deleteRole", notes = "删除角色")
    @ApiImplicitParam(name = "roleId", value = "角色主键", dataType = "String")
    @DeleteMapping("/info/{id}")
    @RequiresPermissions("sys:role:del")
    public R deleteRole(@PathVariable String id){
        String roleId = id.toUpperCase();
        Role role = roleService.getById(roleId);
        if (role == null) {
            return R.error(404, "","失败，角色不存在！");
        }
        if (role.getIsSys() == 1) {
            return R.error("失败，系统默认角色不可删除！");
        }
        if (roleMenuService.isExistRole(roleId)) {
            return R.error("失败,该角色下有资源绑定，请先取消授权！");
        }
        userRoleService.deleteByRoleId(roleId);
        roleService.removeById(role.getRoleId());
        // 添加日志
        String oldValue = JSON.toJSONString(role);
        logService.addLog(LogModule.SYSROLE, LogType.DEL, oldValue, "", role.getRoleId(), this.getUserId(), "删除角色[" + role.getRoleId()+ "]成功");
        return R.ok("成功！");
    }

    @PutMapping("/auth/{id}")
    @RequiresPermissions("sys:role:auth")
    public R authMenu(@PathVariable String id, @RequestBody Map<String, List<Long>> data) {
        String roleId = id.toUpperCase();
        List<Long> add = data.get("add");
        List<Long> del = data.get("remove");
        List<RelRoleMenu> addList = new ArrayList<>();
        for (Long n : add) {
            RelRoleMenu rel = new RelRoleMenu();
            rel.setMenuId(n);
            rel.setRoleId(roleId);
            addList.add(rel);
        }
        try {
            if (add.size() > 0) {
                roleMenuService.addRelBatch(addList);
                // 添加日志
                logService.addLog(LogModule.SYSROLE, LogType.AUTH, "", ArrayUtils.toString(add), roleId, this.getUserId(), "授权成功");
            }
            if (del.size() > 0) {
                roleMenuService.deleteByRoleIdAndMenuIds(roleId, del);
                // 添加日志
                logService.addLog(LogModule.SYSROLE, LogType.UNAUTH, ArrayUtils.toString(del), "", roleId, this.getUserId(), "取消授权成功");
            }
            return R.ok("成功！");
        } catch (Exception e) {
            return R.error("失败！");
        }
    }

    @GetMapping("/relUser/{id}")
    @RequiresPermissions("sys:role:view")
    public R getRoleRelUser(@PathVariable String id) {
        List<RelUserRole> data = userRoleService.getUserInfoByRoleId(id);
        return R.ok(data);
    }

    @GetMapping("/relMenu/{id}")
    @RequiresPermissions("sys:role:view")
    public R getRoleRelMenu(@PathVariable String id) {
        List<Long> data = roleMenuService.getMenusByRoleId(id);
        return R.ok(data);
    }
}
